package 扩展类

import (
	"fmt"
	"net"
	"time"
)

// X取网卡MAC地址 返回系统中所有网卡的MAC地址列表
func X取网卡MAC地址() []string {
	// 初始化MAC地址切片
	var macAddrs []string

	// 获取系统中所有的网络接口
	nets, err := net.Interfaces()
	if err != nil {
		// 如果获取网络接口时发生错误，则直接返回空的MAC地址切片
		return macAddrs
	}

	// 遍历所有网络接口
	for _, net := range nets {
		// 获取当前网络接口的硬件地址（MAC地址）
		macAddr := net.HardwareAddr.String()
		// 如果MAC地址为空，则跳过当前循环
		if len(macAddr) == 0 {
			continue
		}
		// 将有效的MAC地址添加到切片中
		macAddrs = append(macAddrs, macAddr)
	}

	// 返回所有有效的MAC地址列表
	return macAddrs
}

// X转换为IP地址 将给定的域名转换为对应的 IP 地址
// 如果转换失败，则返回错误信息
func X转换为IP地址(域名 string) (string, error) {
	// 验证输入是否为空
	if 域名 == "" {
		return "", fmt.Errorf("转换为IP地址:域名不能为空")
	}
	// 解析 IP 地址
	ipAddr, err := net.ResolveIPAddr("ip", 域名)
	if err != nil {
		return "", fmt.Errorf("转换为IP地址失败: %v", err)
	}
	return ipAddr.String(), nil
}

// X端口是否被占用 检查指定地址和端口是否已被其他服务占用。
// 参数:
// 端口: 需要检查的端口号。
// 返回值:
// 如果端口被占用，则返回true；否则返回false。
func X端口是否被占用(端口 int) bool {
	// 尝试监听端口
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", 端口))
	if err != nil {
		// 如果监听失败，端口可能被占用
		return true
	}
	defer listener.Close()
	// 监听成功，端口可用
	return false
}

func X取可用端口() (int, error) {
	// 创建一个临时监听器，随机分配一个端口
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		return 0, err
	}
	defer listener.Close()

	// 获取监听器的地址
	addr := listener.Addr().(*net.TCPAddr)

	// 返回端口号
	return addr.Port, nil
}

// X是否已联网 检查主机是否连接到互联网。
// 参数:
// -可选dns:允许指定特定的DNS服务器进行连接测试。
func X是否已联网(可选dns ...string) bool {
	// 初始化连接变量，用于后续的网络连接测试。
	var 连接 net.Conn
	var 错误 error
	// 确保在函数结束时，如果建立了连接，则关闭连接。
	defer func() {
		if 连接 != nil {
			连接.Close()
		}
	}()

	// 设置连接超时时间为3秒。
	超时 := time.Second * 3
	// 默认DNS服务器列表，用于测试网络连接。
	dns := []string{
		"223.5.5.5",    // 阿里
		"119.29.29.29", // 腾讯
		"8.8.8.8",      // 谷歌
	}
	// 如果提供了可选DNS参数，则将其添加到DNS服务器列表中。
	if len(可选dns) > 0 {
		dns = append(可选dns, dns...)
	}

	// 遍历DNS服务器列表，尝试建立TCP连接。
	for i := range dns {
		连接, 错误 = net.DialTimeout("tcp", dns[i]+":53", 超时)
		// 如果连接成功，则关闭连接并返回true。
		if 错误 == nil {
			return true
		}
	}

	// 如果所有连接尝试均失败，则返回false。
	return false
}
